package com.woniuxy.portal.model.vo;

import lombok.Data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 购物车对象
 */
@Data
public class CartVo implements Serializable {

    //购物项集合(键是书籍ID，值是购物项对象)
    private Map<Long, CartItemVo> items = new LinkedHashMap<>();
    private Double totalPrice;  //总价格
    private Integer amount;     //总数量
    private Long userId;        //用户的id

    /**
     *  购车添加
     */
    public void add(CartItemVo cartItem) {
        //判断购物车中是否已经存在该商品
        Long bookId = cartItem.getBookId();
        if (items.containsKey(bookId)) {
            //存在，则更新数量
            CartItemVo item = items.get(bookId);
            //把原来的数量进行添加
            //item.getQuantity()     原来的数量
            //cartItem.getQuantity() 新添加的数量
            item.setQuantity(cartItem.getQuantity() + item.getQuantity());
        } else {
            //不存在，则添加
            items.put(bookId, cartItem);
        }
        //更新总价格和总数量
        updateAmountAndTotalPrice();
    }

    /**
     *  修改数量添加
     */
    public void update(Long bookId, Integer quantity) {
        //判断购物车中是否已经存在该商品
        if (items.containsKey(bookId)) {
            //存在，则更新数量
            CartItemVo item = items.get(bookId);
            //把原来的数量进行添加
            //item.getQuantity()     原来的数量
            //cartItem.getQuantity() 新添加的数量
            item.setQuantity(item.getQuantity() + quantity);
        }

        //更新总价
        updateAmountAndTotalPrice();
    }

    /**
     *  删除添加
     */
    public void remove(Long bookId) {
        items.remove(bookId); //移除
        //清理总价
        updateAmountAndTotalPrice();
    }

    /**
     *  更新总价和数量
     */
    public void updateAmountAndTotalPrice() {

        /**
         *   java 语法中 有 4个函数式接口
         *     供给型接口   T get()
         *     断言性结构   boolean predicate(T t)
         *     消费性接口   void  consumer(T t)
         *     函数式接口   K apply(T t)
         */
        /**
         *    stream 流的操作三个步骤
         *      1、创建流      items.values().stream()
         *      2、中间操作
         *                    过滤   filter (断言接口)
         *                    映射   map   （函数式接口）
         *                    排序   sort   (自然排序接口)     Comparable 接口
         *
         *      3、终止操作
         *            forEach(消费接口) consumer(T t)
         *            收集操作 collect(Collector<? super T, A, R> collector)  .sum()
         */
        // 遍历
        //计算   items.values().stream().  拿到集合的流    mapToDouble() 把CartItemVo =>double  .sum()收集求和
        //总价格
        totalPrice = items.values().stream().mapToDouble(CartItemVo::getSum).sum();
        //总数
        amount = items.values().stream().mapToInt(CartItemVo::getQuantity).sum();
    }

    /**
     *  所有的商品
     *
     *  存储商品的事 Map<Long, CartItemVo>  values()
     *  items.values() 拿到所有的 CartItemVo 就是商品
     *  反射 进行序列化的操作的时候 getItemList 认为有 属性 (itemList)
     */
    public List<CartItemVo> getItemList() {
        return new ArrayList<>(items.values());
    }

    /**
     * 清空
     */
    public void clear() {
        items.clear();
        //清理总价
        updateAmountAndTotalPrice();
    }
}